/*
 * Copyright 2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
const execSync = require('child_process').execSync;
const fs = require('fs');

/**
 * Get package latest version.
 *
 * @param name package name.
 * @return string latest version.
 */
function getPackageLatestVersion(name) {
    const execMessage = execSync(`yarn info ${name} version --json`, {encoding: 'utf-8'});
    return JSON.parse(execMessage).data;
}


/**
 * Upgrade package versions.
 *
 * @param packagePath package path.
 * @param ignorePackages ignore packages.
 */
function upgradePackageVersions(packagePath, ignorePackages) {

    // require package json object.
    const packageJson = require(packagePath);
    for (const dependenciesProperty of ["peerDependencies", "dependencies", "devDependencies"]) {
        if (dependenciesProperty in packageJson) {
            const dependencies = packageJson[dependenciesProperty];
            const dependencyNames = Object.keys(dependencies);
            for (const dependencyName of dependencyNames) {
                if (Array.isArray(ignorePackages) && ignorePackages.includes(dependencyName)) {
                    console.info(`ignore ${dependencyName} package.`);
                } else {
                    const latestVersion = getPackageLatestVersion(dependencyName);
                    if (dependencies[dependencyName] !== `^${latestVersion}`) {
                        dependencies[dependencyName] = `^${latestVersion}`;
                        console.info(`${dependencyName} update to latest version: ${latestVersion}`);
                    }
                }
            }
        }
    }

    // write data to package.json.
    fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2));
}

const ignorePackages = [];

const packagePaths = ["./package.json"];

for (const packagePath of packagePaths) {
    upgradePackageVersions(packagePath, ignorePackages);
}
